let canvas = document.getElementById('canvas');

var minDecibels = document.querySelector('#minDecibels');
var maxDecibels = document.querySelector('#maxDecibels');
var fftSize = document.querySelector('#fftSize');
var smoothingTimeConstant = document.querySelector('#smoothingTimeConstant');

var minDecibels_value = document.querySelector('#minDecibels_value');
var maxDecibels_value = document.querySelector('#maxDecibels_value');
var fftSize_value = document.querySelector('#fftSize_value');
var smoothingTimeConstant_value = document.querySelector('#smoothingTimeConstant_value');

var select = document.querySelector('#select');

var canvasCtx = document.getElementById('canvas').getContext('2d');
var stream, audioCtx, drawVisual
async function _play() {
    audioCtx = new(window.AudioContext || window.webkitAudioContext)();

    stream = await navigator.mediaDevices.getUserMedia({ audio: true });


    //创建一个新的 关联 对象
    let source = audioCtx.createMediaStreamSource(stream);


    var analyser = audioCtx.createAnalyser();
    analyser.minDecibels = minDecibels.value; //意思是收集 最低分贝
    analyser.maxDecibels = maxDecibels.value; //结果范围的最大值
    analyser.smoothingTimeConstant = smoothingTimeConstant.value; //分析帧的平均常数 0-1  默认值为 0.8

    source.connect(analyser);

    analyser.fftSize = Math.pow(2, fftSize.value);
    var bufferLength = analyser.frequencyBinCount;
    var dataArray = new Uint8Array(bufferLength);
    source.connect(audioCtx.destination);


    let WIDTH = canvas.width
    let HEIGHT = canvas.height

    // 下面调节的
    minDecibels.oninput = function() {
        analyser.minDecibels = minDecibels.value;
        minDecibels_value.innerHTML = minDecibels.value;
    }

    maxDecibels.oninput = function() {
        analyser.maxDecibels = maxDecibels.value;
        maxDecibels_value.innerHTML = maxDecibels.value;
    }

    fftSize.oninput = function() {
        analyser.fftSize = Math.pow(2, fftSize.value);
        fftSize_value.innerHTML = Math.pow(2, fftSize.value);
    }

    smoothingTimeConstant.oninput = function() {
        analyser.smoothingTimeConstant = smoothingTimeConstant.value;
        smoothingTimeConstant_value.innerHTML = smoothingTimeConstant.value;
    }

    // 下面是画图的
    getByteFrequencyData = () => {
        drawVisual = requestAnimationFrame(getByteFrequencyData);

        analyser.getByteFrequencyData(dataArray);

        canvasCtx.fillStyle = 'rgb(0, 0, 0)';
        canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

        var barWidth = (WIDTH / bufferLength) * 2.5;
        var barHeight;
        var x = 0;

        for (var i = 0; i < bufferLength; i++) {
            barHeight = dataArray[i];

            canvasCtx.fillStyle = 'rgb(' + (barHeight + 100) + ',50,50)';
            canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2);
            /*  
            context.fillRect(x,y,width,height);
            x    矩形左上角的 x 坐标
            y    矩形左上角的 y 坐标
            width    矩形的宽度，以像素计
            height    矩形的高度，以像素计
            */

            x += barWidth + 1;
        }
    };
    getByteTimeDomainData = () => {
        drawVisual = requestAnimationFrame(getByteTimeDomainData);
        analyser.getByteTimeDomainData(dataArray);

        canvasCtx.fillStyle = 'rgb(200, 200, 200)';
        canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

        canvasCtx.lineWidth = 2;
        canvasCtx.strokeStyle = 'rgb(0, 0, 0)';

        var sliceWidth = WIDTH * 1.0 / bufferLength;
        var x = 0;

        canvasCtx.beginPath();
        for (var i = 0; i < bufferLength; i++) {
            let v = dataArray[i] / 128.0,
                y = v * HEIGHT / 2;

            if (i === 0)
                canvasCtx.moveTo(x, y);
            else
                canvasCtx.lineTo(x, y);

            x += sliceWidth;
        }

        canvasCtx.lineTo(canvas.width, canvas.height / 2);
        canvasCtx.stroke();
    };
    if (select.value == 'getByteTimeDomainData') {
        getByteTimeDomainData()
    } else {
        getByteFrequencyData()
    }
    select.addEventListener('change',()=>{
        console.log(select.value)
        cancelAnimationFrame(drawVisual)
        canvasCtx.clearRect(0, 0, WIDTH, HEIGHT)
        if (select.value == 'getByteTimeDomainData') {
            getByteTimeDomainData()
        } else {
            getByteFrequencyData()
        }
    })
}




_close = () => {
    cancelAnimationFrame(drawVisual)
    audioCtx.close()
    stream.getTracks().forEach((track) => {
        track.stop();
    });
}
/*
AnalyserNode.fftSize
一个无符号长整形(unsigned long)的值，代表了用于计算频域信号时使用的 FFT (快速傅里叶变换) 的窗口大小。
 属性的值必须是从32到32768范围内的2的非零幂; 其默认值为2048.

AnalyserNode.frequencyBinCount 只读
一个无符号长整形(unsigned long)的值, 值为fftSize的一半。这通常等于将要用于可视化的数据值的数量。

AnalyserNode.minDecibels
是一个双精度值，表示FFT分析频域数据并转换为无符号字节值时，对输入的功率数据的最小阈值 - 基本上，它限定了调用getByteFrequencyData()时结果范围的最小值

AnalyserNode.maxDecibels
是一个双精度值，表示FFT分析频域数据并转换为无符号字节值时，对输入的功率数据的最大阈值 - 基本上，它限定了调用getByteFrequencyData()时结果范围的最大值

AnalyserNode.smoothingTimeConstant
是一个双精度浮点型(double)的值，表示最后一个分析帧的平均常数 — 基本上，它随时间使值之间的过渡更平滑。

AnalyserNode.getFloatFrequencyData()
将当前频域数据拷贝进Float32Array数组。

AnalyserNode.getByteFrequencyData()
将当前频域数据拷贝进Uint8Array数组（无符号字节数组）。

AnalyserNode.getFloatTimeDomainData()
将当前波形，或者时域数据拷贝进Float32Array数组。

AnalyserNode.getByteTimeDomainData()
将当前波形，或者时域数据拷贝进 Uint8Array数组（无符号字节数组）。 
*/